﻿using Desktop.Interfaces;
using System.ComponentModel;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;

namespace Desktop.Controls
{
    public class Application : TabControl, IApplication
    {
        #region Events

        public event PropertyChangedEventHandler PropertyChanged;

        public static readonly RoutedEvent ClosingEvent =
            EventManager.RegisterRoutedEvent("Closing", RoutingStrategy.Bubble,
                typeof(RoutedEventHandler), typeof(Application));

        public static readonly RoutedEvent PrincipalChangedEvent =
            EventManager.RegisterRoutedEvent("PrincipalChanged", RoutingStrategy.Bubble,
                typeof(RoutedEventHandler), typeof(Application));

        public event RoutedEventHandler Closing
        {
            add
            {
                AddHandler(ClosingEvent, value);
            }
            remove
            {
                RemoveHandler(ClosingEvent, value);
            }
        }

        public event RoutedEventHandler PrincipalChanged
        {
            add
            {
                AddHandler(PrincipalChangedEvent, value);
            }
            remove
            {
                RemoveHandler(PrincipalChangedEvent, value);
            }
        }

        #endregion

        #region Constants

        private const string DEFAULT_NAME = "Application";

        #endregion

        #region Variables

        private string _applicationName;
        private BindingList<IWorkspace> _workspaces;

        #endregion

        #region Constructors

        public Application()
            : base()
        {
            TabStripPlacement = Dock.Top;

            AddHandler(ApplicationTabItem.CloseTabEvent, new RoutedEventHandler(OnCloseTab));
            AddHandler(Application.ClosingEvent, new RoutedEventHandler(OnClosing));
            AddHandler(Application.PrincipalChangedEvent, new RoutedEventHandler(OnPrincipalChanged));

            ApplicationName = DEFAULT_NAME;
            
            Workspaces = new BindingList<IWorkspace>();
            ItemsSource = Workspaces;
        }

        #endregion

        #region Properties

        public string ApplicationName
        {
            get
            {
                return _applicationName;
            }
            set
            {
                if (string.IsNullOrEmpty(value))
                {
                    value = DEFAULT_NAME;
                }
                if (_applicationName != value)
                {
                    _applicationName = value;
                    if (PropertyChanged != null)
                    {
                        PropertyChanged(this, new PropertyChangedEventArgs("ApplicationName"));
                    }
                }
            }
        }

        public BindingList<IWorkspace> Workspaces
        {
            get
            {
                return _workspaces;
            }
            private set
            {
                _workspaces = value;
            }
        }

        #endregion

        #region Methods

        public void OpenWorkspace(IWorkspace workspace)
        {
            workspace.Parent = this;
            Workspaces.Add(workspace);
            SelectedItem = workspace;
        }

        public void CloseWorkspace(IWorkspace workspace)
        {
            if (Workspaces.Contains(workspace))
            {
                workspace.Parent = null;
                int index = Workspaces.IndexOf(workspace) - 1;
                Workspaces.Remove(workspace);
                if (index >= 0)
                {
                    SelectedItem = Workspaces[index];
                }
            }
        }

        public void ActivateWorkspace(IWorkspace workspace)
        {
            SelectedItem = workspace;
        }

        protected override DependencyObject GetContainerForItemOverride()
        {
            return new ApplicationTabItem();
        }

        #endregion

        #region Event Handlers

        private void OnCloseTab(object source, RoutedEventArgs e)
        {
            TabItem tabItem = e.OriginalSource as TabItem;
            Workspace workspace = tabItem.DataContext as Workspace;

            workspace.RaiseEvent(new RoutedEventArgs(Workspace.ClosingEvent, this));

            Workspaces.Remove(workspace);
        }

        protected virtual void OnClosing(object source, RoutedEventArgs e)
        {
            // Close all activities:
            while (Workspaces.Count > 0)
            {
                Workspace workspace = Workspaces[0] as Workspace;
                workspace.RaiseEvent(new RoutedEventArgs(Workspace.ClosingEvent, workspace));
                Workspaces.Remove(workspace);
            }
        }

        protected virtual void OnPrincipalChanged(object source, RoutedEventArgs e)
        {
            List<IWorkspace> workspaces = new List<IWorkspace>(Workspaces);

            foreach (Workspace workspace in workspaces)
            {
                workspace.RaiseEvent(new RoutedEventArgs(Workspace.PrincipalChangedEvent, workspace));
            }
        }

        #endregion
    }
}